﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Crawler.ApplicationServices;
using Crawler.Domain;
using Crawler.Domain.DataEntities;
using Crawler.Domain.DataEntities.Crawling;
using Crawler.Domain.DataEntities.Extracted;
using Crawler.Domain.Sources;
using Crawler.DomainServices.DataServices;
using Crawler.DomainServices.Download;
using Crawler.DomainServices.Pages;

namespace Crawler.Downloaders
{
    class YifyDownloader:IDependencyDownloader
	{
	    private readonly ISourceContentRepository _repository;
	    private readonly IRequestsHelper _requestsHelper;

	    public YifyDownloader(ISourceContentRepository repository,IRequestsHelper requestsHelper)
	    {
		    _repository = repository;
		    _requestsHelper = requestsHelper;
	    }


	    public TorrentSource ForSource
		{
			get
			{
				return TorrentSource.YifyTorrent;
			}
		}
	    public void Store(CrawlingSession session, string urlToProccess, string htmlContent)
	    {
			if(!MustProcess(session,urlToProccess)) return;

		    var filePath=SaveToFile(session,htmlContent);
			
		    var page = new RawPageCrawlInfo
		    {
				 FromUrl = urlToProccess,
				 FilePath = filePath,
				 PageSource =  PageSource.MovieYifyTorrent,
				 ProccessablePageType=ProccessablePageType.MovieFile ,
				 SessionId=session.SessionId,
				 UtcCrawled = DateTime.UtcNow,
				 DownloadStatus = DownloadStatus.Completed
		    };

			_repository.Save(page);

		    YifyMoviePage pg = YifyMoviePage.FromHtml(new MovieProcessableSource(TorrentSource.YifyTorrent, session.SessionId,urlToProccess,htmlContent));
		    SaveTorrentLinksSource(session,pg);

		    StoreImdb(pg.ImdbUrl,session);

			var imdbPage= ImdbMoviePage.FromUrl(pg.ImdbUrl);

			StoreSubtitlesPageAsPending(string.Format("http://www.yifysubtitles.com/movie-imdb/{0}", imdbPage.ImdbId), session);

	    }

	    private void SaveTorrentLinksSource(CrawlingSession session, YifyMoviePage pg)
	    {
		    string url = string.Format(@"http://www.yify-torrent.org/download/torrent-{0}.html", pg.IdInSource);
		    string txt =
				 _requestsHelper.GetPageHtmlText(url);
			var filePath = SaveToFile(session, txt);
			var page = new RawPageCrawlInfo
			{
				FromUrl = url,
				FilePath = filePath,
				PageSource = PageSource.MovieYifyTorrent,
				ProccessablePageType = ProccessablePageType.YifyTorrentFileLink,
				SessionId = session.SessionId,
				UtcCrawled = DateTime.UtcNow,
				DownloadStatus = DownloadStatus.Completed
			};
			_repository.Save(page);
	    }

	    protected bool MustProcess(CrawlingSession session, string url)
		{
			return url.ToLower().StartsWith("http://www.yify-torrent.org/movie/") &&
				   _repository.CountByUrl(session,url) == 0;
		}

	    private void StoreSubtitlesPageAsPending(string url, CrawlingSession session)
	    {

			var page = new RawPageCrawlInfo
			{
				FromUrl = url,
				FilePath = null,
				PageSource = PageSource.YifySubtitle,
				ProccessablePageType = ProccessablePageType.MovieInfo,
				SessionId = session.SessionId,
				UtcCrawled = DateTime.UtcNow,
				DownloadStatus = DownloadStatus.Pending
			};
		    try
		    {
			    _repository.Save(page);
		    }
		    catch (Exception ex)
		    {
			    //TODO: LOG IT WAS ALREADY DOWNLOADED
		    }
	    }

	    private string SaveToFile(CrawlingSession session, string htmlContent)
	    {
			
		    string filePath= Path.Combine(session.Folder, string.Format("{0}.DownloadedContent",Guid.NewGuid().ToString().Replace('-', '_')));

		    File.WriteAllText(filePath,htmlContent);
		    return filePath;
	    }


	    private void StoreImdb(string imdbUrl, CrawlingSession session)
	    {
		    string htmlContent = _requestsHelper.GetPageHtmlText(imdbUrl);

			var filePath = SaveToFile(session, htmlContent);

			var page = new RawPageCrawlInfo
			{
				FromUrl = imdbUrl,
				FilePath = filePath,
				PageSource = PageSource.ImdbMovie,
				ProccessablePageType = ProccessablePageType.MovieInfo,
				SessionId = session.SessionId,
				UtcCrawled = DateTime.UtcNow,
				DownloadStatus = DownloadStatus.Completed
			};

			_repository.Save(page);
	    }
	}
}
